import { IconButton } from 'egret/base/browser/ui/buttons';
import { ComboBox } from 'egret/base/browser/ui/comboboxs';
import { AttributeItemGroup, HGroup } from 'egret/base/browser/ui/containers';
import { DivideLine } from 'egret/base/browser/ui/dividelines';
import { IDropDownTextDataSource } from 'egret/base/browser/ui/dropdowns';
import { TextInput } from 'egret/base/browser/ui/inputs';
import { on } from 'egret/base/common/Boardcast';
import { addClass } from 'egret/base/common/dom';
import { isLinux, isWindows } from 'egret/base/common/platform';
import { localize } from 'egret/base/localization/nls';
import { INode } from 'egret/exts/exml-exts/exml/common/exml/treeNodes';
import { getConfirmMessage1 } from 'egret/platform/dialogs/common/dialogs';
import { MessageBoxOptions } from 'egret/platform/windows/common/windows';
import { showMessageBox } from 'egret/platform/windows/electron-browser/windowClientServices';
import { getWorkspacePath } from 'egret/platform/workspace/common/workspace';
import { LayerPanelUtil } from 'egret/workbench/parts/layers/components/LayerPanelUtil';
import { show_append } from 'egret/workbench/parts/output/browser/OutputView';
import { Scale9WindowPanel } from 'egret/workbench/parts/properties_old/exml-prop/component/scale9window/Scale9WindowPanel';
import { ConfirmResult } from 'egret/workbench/services/editor/common/models';
import { addResByModule } from 'egret/workbench/services/files/fileUtils';
import { showLoading } from 'egret/workbench/services/notification/browser/toasts';
import * as fs from "fs";
import * as path from "path";
import '../../media/propertyView.css';
import '../../media/propertyViewStyle.css';
import { BasePart } from '../../parts/basePart';
/**
 * 原数据部分
 */
export class SourcePart extends BasePart {
	private currentNode: INode = null;
	/**
	 * 关联的属性发生了改变
	 * @param nodes 
	 */
	public doRelatePropsChanged(nodes: INode[]): void {
		this.currentNode = null;
		this.hide();
		if (!this.model) {
			return;
		}
		const targetNodes: INode[] = [];
		for (let i = 0; i < nodes.length; i++) {
			const node = nodes[i];
			if (this.model.getExmlConfig().isInstance(node.getInstance(), 'eui.Image')) {
				targetNodes.push(node);
			}
		}
		nodes = targetNodes;
		if (nodes.length != 1) {
			return;
		}
		this.show();
		const node = nodes[0];
		this.currentNode = node;

		//source
		const sourceValue = node.getProperty('source');
		if (sourceValue) {
			this.sourceInput.text = sourceValue.getInstance();
		} else {
			this.sourceInput.text = '';
		}

		//fillmode
		const fillModeValue = node.getProperty('fillMode');
		const fillModeDefault = node.getInstance()['fillMode'];
		this.fillmodeCombobox.prompt = fillModeDefault;
		if (fillModeValue) {
			this.fillmodeCombobox.setSelection(fillModeValue.getInstance());
		}
	}

	private sourceInput = new TextInput();
	private scale9GridBtn = new IconButton();
	private fillmodeCombobox = new ComboBox();

	/**
	 * 渲染
	 * @param el 
	 */
	protected render(container: HTMLElement): void {
		container.style.display = 'flex';
		container.style.flexDirection = 'column';
		container.style.padding = '4px 0 4px 0';

		const line = new DivideLine(container);
		line.text = localize('property.style.title.source', 'Asset');
		line.style.marginBottom = '6px';

		let attribute = new AttributeItemGroup(container);
		attribute.label = localize('property.style.source.source', 'Asset Name:');
		const hGroup = new HGroup(attribute);
		this.sourceInput.create(hGroup);
		this.toDisposes.push(this.sourceInput.onValueChanged(e => this.sourceChanged_handler(e)));
		this.sourceInput.drop_cb = async function (e: DragEvent) {
			const files = e?.dataTransfer?.files;
			if (!files || !files.length) {
				return;
			}
			const addFiles = [], sourceMap = {};
			const canCopy = function (file: string) {
				return file.includes(".png") || file.includes(".jpg");
			}
			const pushFile = function (file: string) {
				const newName = path.basename(file).replace(".", "_");
				sourceMap[file] = newName;
				addFiles.push(file);
			}
			const readDir = function (dir: string, arr: string[]) {
				let farr = fs.readdirSync(dir);
				farr.forEach((file) => {
					var stat = fs.lstatSync(path.join(dir, file));
					if (stat.isDirectory()) {
						readDir(path.join(dir, file), arr);
					} else if (stat.isFile() && canCopy(file)) {
						pushFile(path.join(dir, file));
					}
				});
			}
			for (var i = 0; i < files.length; i++) {
				const file = files[i];
				const fileName = file.name;
				const filePath = file.path;
				var stat = fs.lstatSync(filePath);
				if (stat.isDirectory()) {
					var stat = fs.lstatSync(filePath);
					readDir(filePath, addFiles);
				} else {
					if (canCopy(fileName)) {
						pushFile(filePath);
					}
				}
			}
			const exmlPath: string = global['__LAYERVIEW'].exmlModeService?.['currrentEditor']?.['_id'];
			let moduleName = exmlPath.replace(path.join(getWorkspacePath(), 'skins'), "");
			moduleName = moduleName.substring(1, moduleName.lastIndexOf('/'));
			const hideLoading = showLoading('正在执行脚本');
			let log = await addResByModule(moduleName, addFiles.join(','));
			hideLoading();
			if (log.includes("相同资源")) {
				let temp = log.match(/相同资源([^\n]+)/gi);
				temp.forEach(str => {
					const arr = str.split(' ');
					sourceMap[arr[1]] = path.basename(arr[2]).replace('.', "_");
				});
			}
			show_append(log);
			if (log.includes("相同名称")) {
				let temp = log.match(/相同名称([^\n]+)/gi);
				const names = temp.map(str => str.split(' ')[1]);

				let message = '';
				if (names.length == 1) {
					message = `已存在名称为 ${names[0]} 的资源，确定替换此资源吗？`;
				} else {
					message = getConfirmMessage1(`已存在以下名称的资源，确定替换如下 ${names.length} 个资源么？`, names);
				}

				const save = { label: names.length > 1 ? '全部替换' : '确定替换', result: ConfirmResult.SAVE };
				const cancel = { label: '取消', result: ConfirmResult.CANCEL };

				const buttons: { label: string; result: ConfirmResult; }[] = [];
				if (isWindows) {
					buttons.push(save, cancel);
				} else if (isLinux) {
					buttons.push(cancel, save);
				} else {
					buttons.push(save, cancel);
				}

				const opts: MessageBoxOptions = {
					title: '提示',
					message: message,
					type: 'warning',
					buttons: buttons.map(b => b.label),
					noLink: true,
					cancelId: buttons.indexOf(cancel)
				};
				if (isLinux) {
					opts.defaultId = 2;
				}

				const result = await showMessageBox(opts);

				if (buttons[result.button].result !== ConfirmResult.SAVE) {
					return;
				}

				const filses = temp.map(str => str.split(' ')[2]).join(',');

				const hideLoading = showLoading('正在执行脚本');
				log = await addResByModule(moduleName, filses, 0, true);
				hideLoading();

				show_append(log);
			}

			const source = Object.values(sourceMap)[0]; 
			this.processTextChanging(source);
			this.processTextChanged(this.text);

			await new Promise<void>((resolve) => {
				var dis = on('exmlModel_refresh', (model) => {
					const node = model.getRootNode();
					const check = function (node) {
						const count: number = node.getNumChildren();
						for (let i: number = 0; i < count; i++) {
							const childNode: INode = node.getNodeAt(i);
							if (LayerPanelUtil.isContainer(childNode)) {
								check(childNode);
							} else {
								if (childNode.getInstance() && childNode.getInstance().source == source) {
									childNode.setSelected(true);
									break;
								}
							}
						}
					}
					check(node);
					dis.dispose();
					resolve();
				})
			})
		}
		this.scale9GridBtn.create(hGroup);
		this.scale9GridBtn.iconClass = 'scale_9_grid';
		this.scale9GridBtn.style.marginLeft = '4px';
		this.toDisposes.push(this.scale9GridBtn.onClick(() => this.scale9gridClick_handler()));
		this.initAttributeStyle(attribute);

		attribute = new AttributeItemGroup(container);
		attribute.label = localize('property.style.source.fillMode', 'Fill Mode:');
		this.fillmodeCombobox.create(attribute);
		this.fillmodeCombobox.setDatas([
			{ id: 'clip', data: 'clip(裁剪)' },
			{ id: 'repeat', data: 'repeat(重复)' },
			{ id: 'scale', data: 'scale(缩放)' },
		]);
		this.toDisposes.push(this.fillmodeCombobox.onSelectChanged(t => this.fillModeChanged_handler(t.getSelection())));
		this.initAttributeStyle(attribute);
	}


	private initAttributeStyle(attribute: AttributeItemGroup): void {
		attribute.labelWidth = 60;
		addClass(attribute.getItemElement(), 'property-attribute-item');
	}


	private sourceChanged_handler(value: string): void {
		console.warn('sourceChanged_handler', value);
		if (!this.currentNode) {
			return;
		}
		if (!value) {
			this.currentNode.setProperty('source', null);
		} else {
			this.currentNode.setString('source', value);
		}
	}

	private scale9gridClick_handler(): void {
		if (!this.currentNode) {
			return;
		}
		if (this.currentNode.getInstance().texture) {
			const nameValue = this.currentNode.getProperty('source');
			const key = nameValue ? nameValue.toString() : '';
			const source = this.currentNode.getInstance().texture._bitmapData ? this.currentNode.getInstance().texture._bitmapData.source : this.currentNode.getInstance().$bitmapData.source;
			if (key && source) {
				const imageObj = {
					// 图片的路径
					src: source.src,
					x: 0,
					y: 0,
					width: this.currentNode.getInstance().texture.textureWidth,
					height: this.currentNode.getInstance().texture.textureHeight,
					imageWidth: this.currentNode.getInstance().texture.textureWidth,
					imageHeight: this.currentNode.getInstance().texture.textureHeight,
					offsetX: this.currentNode.getInstance().texture.$bitmapX,
					offsetY: this.currentNode.getInstance().texture.$bitmapY,
					isSet: false
				};
				const isScale9Grid = this.currentNode.getProperty('scale9Grid');
				// 图片曾经被设置过
				if (isScale9Grid) {
					imageObj.x = isScale9Grid.getInstance().x;
					imageObj.y = isScale9Grid.getInstance().y;
					imageObj.width = isScale9Grid.getInstance().width;
					imageObj.height = isScale9Grid.getInstance().height;
					imageObj.isSet = true;
				}
				const scale9Window = new Scale9WindowPanel(imageObj,
					(v) => {
						if(this.currentNode){
							if (v) {
								this.currentNode.setScale9Grid(v.x + ',' + v.y + ',' + v.width + ',' + v.height);
							} else {
								this.currentNode.setProperty('scale9Grid',null);
							}
						}
					});
				scale9Window.open('root', true);
			}
		}
	}

	private fillModeChanged_handler(value: IDropDownTextDataSource): void {
		if (!this.currentNode) {
			return;
		}
		if (!value) {
			this.currentNode.setProperty('fillMode', null);
		} else {
			this.currentNode.setString('fillMode', value.id);
		}
	}
}